package cn.bookingsmart.service.impl;

import cn.bookingsmart.domain.User;
import cn.bookingsmart.mapper.UserMapper;
import cn.bookingsmart.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

/**
 * Created by sun on 2018/3/7.
 *
 * @author sunfuchang03@126.com
 * @version 1.0
 * @since 1.0
 */
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
@Service
public class UserServiceImpl implements UserService {
    //~ Static fields/initializers =====================================================================================
    private static Logger log = LoggerFactory.getLogger(UserServiceImpl.class);

    //~ Instance fields ================================================================================================

    @Autowired
    private TransactionTemplate transactionTemplate;
    @Autowired
    private UserMapper userMapper;

    //~ Constructors ===================================================================================================


    //~ Methods ========================================================================================================

    //    @Override
//    public void add(User user) throws Exception {
//        // Spring编码式事务，回调机制
//        transactionTemplate.execute(new TransactionCallback<Object>() {
//            @Override
//            public Object doInTransaction(TransactionStatus status) {
//                try {
//                    userMapper.insertSelective(user);
//                } catch (Exception e) {
//                    // 异常，设置为回滚
//                    status.setRollbackOnly();
//                    throw e;
//                }
//                return null;
//            }
//        });
//    }
//
    @Override
    public void add(User user) throws Exception {
        // Spring编码式事务，回调机制
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                try {
                    userMapper.insertSelective(user);
                } catch (Exception e) {
                    // 异常，设置为回滚
                    status.setRollbackOnly();
                    throw e;
                }
            }
        });
    }

    @Override
    public void insert(User user) throws Exception {
        // Spring声明式事务
        userMapper.insertSelective(user);
        // 模拟抛出异常，事务回滚
        throw new Exception("hahaha");
    }

    // 方法不受事务控制，可以正常插入数据
//    @Override
//    public void tryInsert(User user) throws Exception {
//        userMapper.insert(user);
//        // 模拟抛出异常，事务回滚
//        throw new Exception("hahaha");
//    }

    // 方法受事务控制，但是抛出的是Exception，默认不会滚，可以正常插入数据
//    @Transactional(propagation = Propagation.REQUIRED)
//    @Override
//    public void tryInsert(User user) throws Exception {
//        userMapper.insert(user);
//        // 模拟抛出异常，事务回滚
//        throw new Exception("hahaha");
//    }

    // 方法受事务控制，而且抛出RuntimeException，事务回滚，无法插入数据
    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void tryInsert(User user) throws Exception {
        userMapper.insert(user);
        // 模拟抛出异常，事务回滚
        throw new NullPointerException("hahaha");
    }
}
